package com.assignwork.service.impl;

import com.assignwork.dto.VoyageBillCabinSearchDTO;
import com.assignwork.dto.VoyageBillCabinSubmitByCabinDTO;
import com.assignwork.dto.VoyageBillCabinSubmitDTO;
import com.assignwork.entity.VoyageBillCabin;
import com.assignwork.mapper.VoyageBillCabinMapper;
import com.assignwork.service.IVoyageBillCabinService;
import com.assignwork.vo.BillAllCabinPageVO;
import com.assignwork.vo.StartedCabinVO;
import com.assignwork.vo.VoyageBillCabinSimpleVO;
import com.assignwork.vo.VoyageBillSplitCabinPageVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.aspectj.apache.bcel.generic.TABLESWITCH;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.system.cache.DictBizCache;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 舱图实现类
 */
@Service
public class VoyageBillCabinServiceImpl extends BaseServiceImpl<VoyageBillCabinMapper, VoyageBillCabin> implements IVoyageBillCabinService {

    private final static BigDecimal DECIMAL_ZERO = new BigDecimal(0);

    @Override
    public IPage<BillAllCabinPageVO> selectVoyageBillCabinAllPage(VoyageBillCabinSearchDTO dto, IPage<BillAllCabinPageVO> page) {
        List<BillAllCabinPageVO> data;
        if ("I".equals(dto.getImpExp())) {
            data = baseMapper.selectImpBillInfo(dto, page);
        } else {
            data = baseMapper.selectExpBillInfo(dto, page);
        }

        return page.setRecords(data);
    }

    @Override
    public Boolean submitVoyageBillCabin(VoyageBillCabinSubmitDTO dto) {
        QueryWrapper<VoyageBillCabin> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(VoyageBillCabin::getIsDeleted , 0)
                .eq(VoyageBillCabin::getSourceId, dto.getSourceId())
                .eq(VoyageBillCabin::getVoyageId, dto.getVoyageId())
                .eq(VoyageBillCabin::getCabinKey, dto.getCabinKey())
                .last("limit 1");
        VoyageBillCabin voyageBillCabin = baseMapper.selectOne(queryWrapper);
        if (!Func.isNull(voyageBillCabin) && !Func.isNull(voyageBillCabin.getId())) {
            voyageBillCabin.setCargoTon(dto.getCargoTon());
            voyageBillCabin.setWorkTon(dto.getWorkTon());
            voyageBillCabin.setRemainder(dto.getRemainder());
        } else {
            voyageBillCabin = new VoyageBillCabin();
            voyageBillCabin.setSourceId(dto.getSourceId());
            voyageBillCabin.setVoyageId(dto.getVoyageId());
            voyageBillCabin.setCabinKey(dto.getCabinKey());
            voyageBillCabin.setCargoTon(dto.getCargoTon());
            voyageBillCabin.setWorkTon(dto.getWorkTon());
            voyageBillCabin.setRemainder(dto.getRemainder());
        }
        return super.saveOrUpdate(voyageBillCabin);
    }

    @Override
    public IPage<VoyageBillCabinSimpleVO> selectVoyageBillCabinBillPage(VoyageBillCabinSearchDTO dto, IPage<VoyageBillCabinSimpleVO> page) {
        List<VoyageBillCabinSimpleVO> data = baseMapper.selectVoyageBillCabinBillList(dto, page);
        for (VoyageBillCabinSimpleVO vo : data) {
            vo.setCabinName(DictBizCache.getValue("hold", vo.getCabinKey()));
        }
        return page.setRecords(data);
    }

    @Override
    public IPage<VoyageBillSplitCabinPageVO> selectVoyageBillSpiltCabinPage(VoyageBillCabinSearchDTO dto, IPage<VoyageBillSplitCabinPageVO> page) {
        List<VoyageBillSplitCabinPageVO> data = baseMapper.selectVoyageBillSpiltCabinList(dto, page);
        return page.setRecords(data);
    }

    @Override
    public BigDecimal getTallyTon(VoyageBillCabinSearchDTO dto) {
        BigDecimal tallyTon = baseMapper.getTallyTon(dto);
        return Func.isNull(tallyTon)?new BigDecimal(0):tallyTon;
    }

    @Override
    public Map<String, StartedCabinVO> cabinTonByShip(Long shipId, String voyageNo) {
        List<StartedCabinVO> vos = this.baseMapper.cabinTonByShip(shipId, voyageNo);
        return vos.stream().collect(Collectors.toMap(StartedCabinVO::getCabin, a -> a, (k1, k2) -> k1));
    }

    @Override
    public boolean submitByCabin(VoyageBillCabinSubmitByCabinDTO dto) {
        if (Func.isNull(dto.getCabins()) || Func.isBlank(dto.getCabins())) {
            return true;
        }
        String[] cabinsList = dto.getCabins().split(",");
        for (String cabin : cabinsList) {
            if (!cabin.isEmpty()) {
                QueryWrapper<VoyageBillCabin> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().eq(VoyageBillCabin::getIsDeleted, 0)
                        .eq(VoyageBillCabin::getSourceId, dto.getSourceId())
                        .eq(VoyageBillCabin::getVoyageId, dto.getVoyageId())
                        .eq(VoyageBillCabin::getBillNo, dto.getBillNo())
                        .eq(VoyageBillCabin::getCabinKey, cabin)
                        .last("Limit 1");
                VoyageBillCabin voyageBillCabin = baseMapper.selectOne(queryWrapper);
                if (Func.isNull(voyageBillCabin)) {
                    VoyageBillCabin newBillCabin = new VoyageBillCabin();
                    newBillCabin.setBillNo(dto.getBillNo());
                    newBillCabin.setVoyageId(dto.getVoyageId());
                    newBillCabin.setSourceId(dto.getSourceId());
                    newBillCabin.setCargoPackage(dto.getCargoPackage());
                    newBillCabin.setCargoName(dto.getCargoName());
                    newBillCabin.setCabinKey(cabin);
                    VoyageBillCabinSearchDTO searchTallyTon = new VoyageBillCabinSearchDTO();
                    searchTallyTon.setShipNameZh(dto.getShipNameZh());
                    searchTallyTon.setVoyage(dto.getVoyage());
                    searchTallyTon.setBillNo(dto.getBillNo());
                    BigDecimal tallyTon = getTallyTon(searchTallyTon);
                    if (Func.isNull(tallyTon)) {
                        tallyTon = new BigDecimal(0);
                    }
                    newBillCabin.setCargoPiece(dto.getCargoPiece());
                    newBillCabin.setCargoTon(dto.getCargoTon());
                    newBillCabin.setWorkTon(tallyTon);
                    newBillCabin.setRemainder(dto.getCargoTon().subtract(tallyTon));
                    super.saveOrUpdate(newBillCabin);
                }
            }
        }
        return true;
    }

    @Override
    public VoyageBillCabinSimpleVO detail(VoyageBillCabinSearchDTO dto) {
        VoyageBillCabinSimpleVO res = new VoyageBillCabinSimpleVO();
        res.setCargoTon(DECIMAL_ZERO);
        res.setWorkTon(DECIMAL_ZERO);
        res.setRemainder(DECIMAL_ZERO);

        QueryWrapper<VoyageBillCabin> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(VoyageBillCabin::getIsDeleted, 0)
                .eq(VoyageBillCabin::getSourceId, dto.getSourceId())
                .eq(VoyageBillCabin::getVoyageId, dto.getVoyageId())
                .eq(VoyageBillCabin::getCabinKey, dto.getCabinKey())
                .last("Limit 1");
        VoyageBillCabin voyageBillCabin = baseMapper.selectOne(queryWrapper);
        if (!Func.isNull(voyageBillCabin) && !Func.isNull(voyageBillCabin.getId())) {
            res.setId(voyageBillCabin.getId());
            res.setVoyageId(voyageBillCabin.getVoyageId());
            res.setSourceId(voyageBillCabin.getSourceId());
            res.setCabinKey(voyageBillCabin.getCabinKey());
            res.setCargoTon(voyageBillCabin.getCargoTon());
            res.setWorkTon(voyageBillCabin.getWorkTon());
            res.setRemainder(voyageBillCabin.getRemainder());
        }
        return res;
    }
}